package com.bases {
	import com.Event.ScrollBarEvent;
	import com.Timer.FrameTimer;
	import com.Timer.FrameTimerEvent;
	import com.debug.TDebug;
	import config.TConfig;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.utils.getTimer;

	public class TScrollBar extends TUIComponent {
		protected var btnUp:ImageButton;
		protected var btnDown:ImageButton;
		protected var btnTrack:ImageButton;
		protected var btnScroll:ImageButton;
		public static var BUTTON_HEIGHT:int = 13;
		public static var BUTTON_WIDTH:int = 15;
		protected var isMouseUp:Boolean = true;
		protected var totalPixels:Number;
		protected var poleStartY:Number;
		protected var scrollText:TextField;
		//计时(用于鼠标放在两个按钮上)
		protected var frameTimer:FrameTimer;
		//鼠标放在按钮上面
		protected var target:Sprite;
		//down:为点按下按钮,up:为点按上按钮
		protected var type:String = '';
		//是否按下两个按钮(向上或向下)
		protected var isBtnDown:Boolean = false;

		public function TScrollBar(scrollText:TextField){
			super();
			this.scrollText = scrollText;
			btnUp = new ImageButton(ScroolUp, ScroolUp, ScroolUp);
			btnDown = new ImageButton(ScroolDown, ScroolDown, ScroolDown);
			btnTrack = new ImageButton(ScroolTrack, ScroolTrack, ScroolTrack);
			btnScroll = new ImageButton(ScroolBar, ScroolBar, ScroolBar);
			this.addChilds(btnUp, btnDown, btnTrack, btnScroll);
			this.setSize(20, 70);
			this.btnScroll.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			this.btnDown.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			this.btnUp.addEventListener(MouseEvent.MOUSE_DOWN, onUp);
			this.scrollText.addEventListener(Event.SCROLL, onScrollEvent);
			this.btnTrack.addEventListener(MouseEvent.MOUSE_DOWN, onBackBGDown);
			frameTimer = new FrameTimer(200, 0);
			frameTimer.addEventListener(FrameTimerEvent.TIMER, onTimer);
		}

		override protected function relayout():void {
			this.btnUp.setPos(0, 0);
			this.btnDown.setPos(0, this.height - BUTTON_HEIGHT);
			this.btnScroll.setPos(0, BUTTON_HEIGHT);
			this.btnTrack.setPos(0, BUTTON_HEIGHT);
			this.btnTrack.setSize(BUTTON_WIDTH, this.height - 2 * BUTTON_HEIGHT);
			this.btnScroll.setSize(BUTTON_WIDTH, 3 * BUTTON_HEIGHT);
			poleStartY = BUTTON_HEIGHT;
		}

		private function onBackBGDown(event:MouseEvent):void {
			var nowPosition:Number;
			if ((mouseY - this.btnUp.y) < (this.btnScroll.height / 2)){
				nowPosition = Math.floor(this.btnUp.y + BUTTON_HEIGHT);
			} else if ((this.btnDown.y - mouseY) < btnScroll.height / 2){
				nowPosition = Math.floor(btnDown.y - btnScroll.height);
			} else {
				nowPosition = mouseY - btnScroll.height / 2;
			}
			btnScroll.y = nowPosition;
			scrollText.scrollV = (scrollText.maxScrollV - 1) * (nowPosition - poleStartY) / totalPixels + 2;
			var unitPixels:Number = totalPixels / (scrollText.maxScrollV - 1);
			if ((nowPosition - poleStartY) < unitPixels){
				scrollText.scrollV = (scrollText.maxScrollV - 1) * (nowPosition - poleStartY) / totalPixels + 1;
			}
		}

		private function onScrollEvent(event:Event):void {
			if (this.scrollText.maxScrollV != 1){
				this.visible = true;
				//定义一个高度因子，此因子随加载文本的增多，将无限趋向于1
				var heightVar:Number = 1 - (scrollText.maxScrollV - 1) / scrollText.maxScrollV;
				this.setThumbHeight(heightVar, this.scrollText.scrollV, this.scrollText.maxScrollV);
			} else {
				this.visible = false;
			}
		}

		private function onUp(event:MouseEvent):void {
			scrollText.scrollV--;
			this.thumbScrollV();
			this.addTargetEvent(this.btnUp, 'up');
		}

		private function addTargetEvent(_target:Sprite, type:String):void {
			this.scrollText.removeEventListener(Event.SCROLL, onScrollEvent);
			this.target = _target;
			isBtnDown = true;
			this.type = type;
			this.frameTimer.start();
			TConfig.getInstance().stage.addEventListener(MouseEvent.MOUSE_UP, onTargetUp);
			target.addEventListener(MouseEvent.MOUSE_UP, onTargetUp);
			this.target.addEventListener(MouseEvent.MOUSE_OUT, onDownMouseOut);
		}

		private function onTargetUp(event:MouseEvent):void {
			if (isBtnDown){
				this.scrollText.addEventListener(Event.SCROLL, onScrollEvent);
				isBtnDown = false;
				this.frameTimer.stop();
				this.target.removeEventListener(MouseEvent.MOUSE_UP, onTargetUp);
				TConfig.getInstance().stage.removeEventListener(MouseEvent.MOUSE_UP, onTargetUp);
			}
		}

		private function onDown(event:MouseEvent):void {
			scrollText.scrollV++;
			this.thumbScrollV();
			this.addTargetEvent(this.btnDown, 'down');
		}

		private function onDownMouseOut(event:MouseEvent):void {
			this.frameTimer.stop();
		}

		private function onTimer(event:FrameTimerEvent):void {
			if (type == 'down'){
				scrollText.scrollV++;
			} else {
				scrollText.scrollV--;
			}
			this.thumbScrollV();
		}

		public function setThumbHeight(value:Number, scrollV:Number, maxScrollV:Number):void {
			//根据高度因子初始化滑块的高度
			this.btnScroll.setSize(this.btnScroll.width, Math.floor(this.btnTrack.height * Math.pow(value, 1 / 3)));
			totalPixels = Math.floor(this.btnDown.y - this.btnTrack.y - this.btnScroll.height);
			this.thumbScrollV();
		}

		private function thumbScrollV():void {
			this.btnScroll.y = Math.floor(poleStartY + totalPixels * (scrollText.scrollV - 1) / (scrollText.maxScrollV - 1));
		}

		override public function setSize(w:Number, h:Number):void {
			super.setSize(w, h);
			this.relayout();
		}

		private function onStageMouseUp(event:MouseEvent):void {
			this.onMouseUp(event);
		}

		private function onMouseDown(event:MouseEvent):void {
			scrollText.removeEventListener(Event.SCROLL, onScrollEvent);
			btnScroll.startDrag(false, new Rectangle(0, BUTTON_HEIGHT, 0, this.height - 2 * BUTTON_HEIGHT - btnScroll.height));
			isMouseUp = false;
			btnScroll.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			TConfig.getInstance().stage.addEventListener(MouseEvent.MOUSE_MOVE, onStateMove);
			TConfig.getInstance().stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
		}

		private function onStateMove(event:MouseEvent):void {
			//在滚动过程中及时获得滑块所处位置
			var nowPosition:Number = Math.floor(this.btnScroll.y);
			//使文本随滚动条滚动,这里为什么要加1，可见scroll属性值应该是取正的，也就是说它会删除小数部分，而非采用四舍五入制？
			scrollText.scrollV = (scrollText.maxScrollV - 1) * (nowPosition - poleStartY) / totalPixels + 2;
			//误差校正
			var unitPixels:Number = totalPixels / (scrollText.maxScrollV - 1);
			if ((nowPosition - poleStartY) < unitPixels){
				scrollText.scrollV = (scrollText.maxScrollV - 1) * (nowPosition - poleStartY) / totalPixels;
			}
		}

		//鼠标弹起,或鼠标离开
		private function onMouseUp(event:MouseEvent):void {
			if (!isMouseUp){
				isMouseUp = true;
				btnScroll.stopDrag();
				btnScroll.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
				TConfig.getInstance().stage.removeEventListener(MouseEvent.MOUSE_MOVE, onStateMove);
				this.scrollText.addEventListener(Event.SCROLL, onScrollEvent);
				TConfig.getInstance().stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			}
		}
	}
}